package com.damai.timer.impl;

import java.lang.reflect.Method;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.SchedulerException;

import com.citywithincity.api.ApiConfig;
import com.citywithincity.utils.CachedClassUtil;
import com.citywithincity.utils.ClassUtil;
import com.damai.aop.MethodCaller;
import com.damai.aop.impl.DefaultMethodCaller;
import com.damai.jobcenter.QuartzPlugin;
import com.damai.timer.TimerJob;
import com.damai.timer.TimerJobFactory;
import com.damai.utils.QuartzJob.QuartzJobListener;

public class TimerUtil {
	
	
	public static String getCorn(Class<? extends TimerJobFactory> clazz,int time){
		TimerJobFactory factory = CachedClassUtil.newInstance(clazz);
		return factory.cron(time);
	}
	
	public static class SECONDS {
		public static class EVERY extends BaseTimerJobFactory{
			public EVERY() {
				super("*/%d * * * * ?");
			}
		}
		public static class TO extends BaseTimerJobFactory{
			public TO() {
				super("%d * * * * ?");
			}
		}
	}
	
	
	public static class MINUTES {
		public static class EVERY extends BaseTimerJobFactory{
			public EVERY() {
				super("0 */%d * * * ?");
			}
		}
		public static class TO extends BaseTimerJobFactory{
			public TO() {
				super("0 %d * * * ?");
			}
		}
	}
	public static class HOURS {
		public static class EVERY extends BaseTimerJobFactory{
			public EVERY() {
				super("0 0 */%d * * ?");
			}
		}
		public static class TO extends BaseTimerJobFactory{
			public TO() {
				super("0 0 %d * * ?");
			}
		}
	}
	
	
	
	public static void proxy(Object orgModel, Object proxyModel) {
		//QuartzPlugin.me().startJob(corn, name, listener);
		Method[] methods = ClassUtil.getPublicMethods(orgModel.getClass());
		for (Method method : methods) {
			if(method.isAnnotationPresent(TimerJob.class)){
				
				TimerJob job = method.getAnnotation(TimerJob.class);
				
				Class<? extends TimerJobFactory> classOfFactory;
				int time;
				
				if(ApiConfig.debug()){
					classOfFactory = job.testCron();
					time = job.testTime();
				}else{
					classOfFactory = job.cron();
					time = job.time();
				}
				
				TimerJobFactory factory = CachedClassUtil.newInstance(classOfFactory);
				String cron = factory.cron(time);
				
				StringBuilder sb = new StringBuilder();
				String name = sb.append(orgModel.getClass().getName()).append(method.getName()).toString();
				
				try {
					QuartzPlugin.me().startJob(cron, name, 
							new TimerJobListener( orgModel, 
							new DefaultMethodCaller(method)
									));
				} catch (SchedulerException e) {
					throw new RuntimeException( "Create timer job fail!" + orgModel.getClass().getName() + ":" + method.getName() ,e);
				}
				
			}
		}
		
	}
	
	private static class TimerJobListener implements QuartzJobListener{

		private Object model;
		private MethodCaller caller;
		
		public TimerJobListener( Object model,MethodCaller caller){
			this.model = model;
			this.caller = caller;
		}
		
		@Override
		public void onExcecuteJob(JobExecutionContext context) throws JobExecutionException {
			try{
				caller.call(model,new Object[]{});
			}catch(RuntimeException e){
				if(e.getCause() != null){
					throw new JobExecutionException(e.getCause());
				}else{
					throw new JobExecutionException(e);
				}
			}
			
		}
		
	}
}
